package com.atguigu.spzx.common.config;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * @author LT
 * @create 2024-03-26-13:52
 */
@Configuration
@EnableCaching //启用缓存管理
public class RedisConfig {

    @Resource
    RedisTemplate redisTemplate; //手动管理缓存时使用

    //jdk原生注解： 标注的方法会在当前类的对象初始化后调用
    @PostConstruct
    public void init(){
        //键 和hash的属性名Key  都使用字符串类型的序列化器
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //值 和hash的属性值Value  都使用json序列化器
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        //设置redis String List Set ZSet类型的键和值序列化器
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);

        //设置redis Hash类型的 属性 和值 序列化器
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);


    }


//    @Cacheable : 一般在查询业务方法上使用
//            当缓存存在时返回缓存
//    缓存不存在时执行业务后将结果缓存
//
//    @CachePut ： 一般在新增业务方法上使用
//            将新增的结果缓存
//    @CacheEvict： 一般在更新/新增/删除方法上使用
//            删除缓存



    //自动缓存管理时使用
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory connectionFactory){

        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //缓存管理配置对象
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                //过期时间配置
                .entryTtl(Duration.ofMinutes(60)) // ttl: time to live
                //.disableCachingNullValues() 禁止缓存空值，默认缓存空值
                //键值序列化器
                .serializeKeysWith(RedisSerializationContext .SerializationPair.fromSerializer(stringRedisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));

        //.prefixCacheNameWith("spzx")
        //connectionFactory:redis的连接工厂对象
        RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(cacheConfiguration)
                .build();
        return cacheManager;

    }








}
